#include<iostream>
#include<vector>
#include<SDL.h>
#include<SDL_image.h>
#include<SDL_mixer.h>
#include<SDL_ttf.h>
#include<string>
using namespace std;
SDL_Surface *screen=NULL;
SDL_Surface *tictac=NULL;
SDL_Surface *background=NULL;
char board[3][3];
const char circle='o',cross='x';
class Button
{
	public: 
		//The attributes of the button 
		SDL_Rect box; 
		//The part of the button sprite sheet that will be shown 
		SDL_Rect clips[4]; 		
	public: 
		Button();
		void show();
		void highlight();
		void unhighlight();
		void click1();
		void click2();		
};
SDL_Surface * load_image(string filename)
{
	SDL_Surface *loadedimage=NULL,*optimisedimage=NULL;
	loadedimage=IMG_Load(filename.c_str());
	if(loadedimage !=NULL)
	{
		optimisedimage = SDL_DisplayFormat( loadedimage );
		//Free the old image 
		SDL_FreeSurface( loadedimage ); 
		if( optimisedimage != NULL ) 
		{ 
			//Map the color key 
			Uint32 colorkey = SDL_MapRGB( optimisedimage->format, 255, 255, 255 ); 
			//Set all pixels of color R 255, G 255, B 255 to be transparent 
			SDL_SetColorKey( optimisedimage, SDL_SRCCOLORKEY, colorkey );
		}
	}
	return optimisedimage;
}
void blitsurface(int x,int y,SDL_Surface* source, SDL_Surface* destination,SDL_Rect *clip=NULL )
{
	SDL_Rect offset; 
	//Give the offsets to the rectangle 
	offset.x = x; 
	offset.y = y;
	//Blit the surface 
	SDL_BlitSurface( source,clip, destination, &offset );
}
void Button::highlight()
{
	blitsurface(box.x,box.y,tictac,screen,&clips[0]);
}
void Button::unhighlight()
{
	SDL_Surface *image;
	image=IMG_Load("tictactoe.png");
	blitsurface(box.x,box.y,image,screen,&clips[3]);
}
void Button::click1()
{
	blitsurface(box.x,box.y,tictac,screen,&clips[1]);
}
void Button::click2()
{
	blitsurface(box.x,box.y,tictac,screen,&clips[2]);
}
Button::Button()
{
	box.x = 0; 
	box.y = 0; 
	box.w = 50; 
	box.h = 50;
	clips[0].x = 120; 
	clips[0].y = 1; 
	clips[0].w = 50; 
	clips[0].h = 50;
	clips[1].x = 1; 
	clips[1].y = 1; 
	clips[1].w = 50; 
	clips[1].h = 50; 
	clips[2].x = 60; 
	clips[2].y = 1; 
	clips[2].w = 50; 
	clips[2].h = 50; 
	clips[3].x = 200; 
	clips[3].y = 1; 
	clips[3].w = 50; 
	clips[3].h = 50;	
}
bool sound(int choice)
{
	Mix_Chunk *music = NULL;
	if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ) 
	{
		return false; 
	}
	Mix_Init(MIX_INIT_MP3);
	switch(choice)
	{
	case 1:
		music = Mix_LoadWAV("player1wins.mp3"); 
		//If there was a problem loading the music 
		if( music == NULL )
		{ 
			return false;
		}
		Mix_PlayChannel (2, music, 1);
		break;
	case 2:
		music = Mix_LoadWAV("player2wins.mp3"); 
		//If there was a problem loading the music 
		if( music == NULL )
		{ 
			return false;
		}
		Mix_PlayChannel (2, music, 1);
		break;
	case 3:
		music = Mix_LoadWAV("player1wins.mp3");  
		//If there was a problem loading the music 
		if( music == NULL )
		{ 
			return false;
		}
		break;
	case 4:
		music = Mix_LoadWAV("player1wins.mp3"); 
		//If there was a problem loading the music 
		if( music == NULL )
		{ 
			return false;
		}
		break;
	default:
		return false;
	}
	return true;
}
int check_victory()
{
	TTF_Init();
	TTF_Font *font = NULL;
	SDL_Color textColor = { 139, 0, 0 };
	font = TTF_OpenFont( "Arbat.ttf", 16 );
	SDL_Surface *message = NULL;
	if(((board[0][0]==cross) && (board[0][1]==cross) && (board[0][2]==cross))||((board[1][0]==cross) && (board[1][1]==cross) && (board[1][2]==cross))||((board[2][0]==cross) && (board[2][1]==cross) && (board[2][2]==cross))||((board[0][0]==cross) && (board[1][1]==cross) && (board[2][2]==cross))||((board[0][2]==cross) && (board[1][1]==cross) && (board[2][0]== cross))||((board[0][0]==cross) && (board[1][0]==cross) && (board[2][0]==cross))||((board[0][1]==cross) && (board[1][1]==cross) && (board[2][1]==cross))||((board[0][2]==cross) && (board[1][2]==cross) && (board[2][2]==cross)))
        { 
			SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) ); 
			message = TTF_RenderText_Solid( font, "Player 1 wins", textColor );
			blitsurface(2,75,message,screen);
			sound(1);
            return 1;
        }
    else if(((board[0][0]==circle) && (board[0][1]==circle) && (board[0][2]==circle))||((board[1][0]==circle) && (board[1][1]==circle) && (board[1][2]==circle))||((board[2][0]== circle) && (board[2][1]==circle) && (board[2][2]==circle))||((board[0][0]==circle) && (board[1][1]==circle) && (board[2][2]==circle))||((board[0][2]==circle) && (board[1][1]==circle) && (board[2][0]==circle))||((board[0][0]==circle) && (board[1][0]==circle) && (board[2][0]==circle))||((board[0][1]==circle) && (board[1][1]==circle) && (board[2][1]==circle))||((board[0][2]==circle) && (board[1][2]==circle) && (board[2][2]==circle)))
        {
			SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) ); 
			message = TTF_RenderText_Solid( font, "Player 2 wins", textColor );
			blitsurface(2,75,message,screen);
			sound(2);
            return 2;
        }
	else
		return 0;
}
int main(int argc, char* args[])
{
	int count=0,x=0,y=0,tempx=0,tempy=0,ptempx=0,ptempy=0,victory=0;
	Button grid[3][3];
	bool flag[3][3];
	bool quit=false;
	SDL_Event event;
	/*if(sound(1)==true)
		return 0;*/
	for(int row=0;row<3;row++)
	{
		for(int col=0;col<3;col++)
		{
			flag[row][col]=false;
			if(row==0)
			{
				for(int i=0;i<col;i++)
					grid[row][col].box.x+=50;
			}
			if(row==1)
			{
				if(col==0)
					grid[row][col].box.y=50;
				for(int i=0;i<col;i++)
				{
					grid[row][col].box.x+=50;
					grid[row][col].box.y=50;
				}
			}
			if(row==2)
			{
				if(col==0)
					grid[row][col].box.y=100;
				for(int i=0;i<col;i++)
				{
					grid[row][col].box.x+=50;
					grid[row][col].box.y=100;
				}
			}
		}
	}
	SDL_Init( SDL_INIT_EVERYTHING );
	screen=SDL_SetVideoMode(150,150,32,SDL_SWSURFACE);
	SDL_WM_SetCaption( "tictactoe", NULL );
	tictac=load_image("tictactoe.png");
	background=IMG_Load("back.png");
	SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) ); 
	while( quit == false)
	{ 
 
		if( SDL_Flip( screen ) == -1 ) 
		{
			return 1;
		}
		if( SDL_PollEvent( &event ) )
		{ 
			if( event.type == SDL_MOUSEMOTION )
			{ 
				x = event.motion.x; 
				y = event.motion.y;
				tempx=(int)x/50;
				tempy=(int)y/50;
				if(flag[tempy][tempx]==false)
					grid[tempy][tempx].highlight();
				if((!(ptempx==tempx) || !(ptempy==tempy))&&flag[ptempy][ptempx]==false)
					grid[ptempy][ptempx].unhighlight();
				ptempx=tempx;
				ptempy=tempy;				
			}			
			if( event.type == SDL_MOUSEBUTTONDOWN ) 
			{ 
				//If the left mouse button was pressed 
				if( event.button.button == SDL_BUTTON_LEFT )
				{ 
					x = event.button.x; 
					y = event.button.y;
					tempx=(int)x/50;
					tempy=(int)y/50;
					if(count%2==0 && flag[tempy][tempx]!=true)
					{
						grid[tempy][tempx].click1();
						flag[tempy][tempx]=true;
						count++;
						board[tempy][tempx]=cross;
					}
					else if(flag[tempy][tempx]!=true)
					{
						grid[tempy][tempx].click2();
						flag[tempy][tempx]=true;
						count++;
						board[tempy][tempx]=circle;
					}										
				}
				victory=check_victory();
				if(victory==1 || victory==2)
					break;
				if((victory!=1 || victory!=2)&& count==9)
				{
					TTF_Font *font = NULL;
					SDL_Color textColor = { 139, 0, 0 };
					font = TTF_OpenFont( "Arbat.ttf", 16 );
					SDL_Surface *message = NULL;	
					SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) ); 
					message = TTF_RenderText_Solid( font, "Match Drawn", textColor );
					blitsurface(2,75,message,screen);
				}
			}			
			if( event.type == SDL_QUIT ) 
			{ 
				quit = true; 
			} 
		} 		 
	}
	if( SDL_Flip( screen ) == -1 ) 
	{
		return 1;
	}	
	SDL_Delay(1000);
	return 0;
}


